/* 
 * Copyright (c) 2012, Fromentin Xavier, Schnell Michaël, Dervin Cyrielle, Brabant Quentin
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *      * The names of its contributors may not be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Fromentin Xavier, Schnell Michaël, Dervin Cyrielle OR Brabant Quentin 
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package kameleon.gui.view;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import kameleon.exception.FileReadingException;
import kameleon.gui.exception.UnknownKeyException;
import kameleon.gui.language.SwitchLanguage;
import kameleon.gui.model.Model;
import kameleon.gui.util.FileConstants;
import kameleon.gui.util.ImageUtility;
import kameleon.gui.util.LanguageConstants;
import kameleon.plugin.PlugInInfo;

/**
 * View displaying known information about an installed plug-in.
 * 
 * @author		Schnell Michaël
 * @version		1.0
 */
public class ViewPlugInInfo extends JPanel
implements FileConstants, LanguageConstants {

	/**
	 * Needed to serialize this class.
	 * 
	 * @see		java.io.Serializable
	 */
	private static final long serialVersionUID = -2180132447515028067L;

	/**
	 * Informations about the displayed plug-in.
	 */
	protected PlugInInfo plugInInfo ;
	
	/**
	 * Layout manager used by this view.
	 */
	protected GridBagLayout gridbag ;
	
	/**
	 * Component displaying the icon of the plug-in.
	 */
	protected JLabel plugInIcon ;
	
	/**
	 * Model for this view.
	 */
	protected Model model ;

	/**
	 * Sole constructor.
	 * 
	 * @param	model
	 * 			model attached to this view
	 * 
	 * @param 	plugInInfo
	 * 			information about the displayed plug-in
	 * 
	 * @param 	grayed
	 * 			whether the icon should be grayed out ({@code true} will 
	 * 			trigger the use of a grayed icon)
	 * 
	 * @throws 	FileReadingException
	 * 			if the format icon could not be loaded
	 * 
	 * @throws 	UnknownKeyException
	 * 			if an error occurred while updating the text of this view
	 */
	public ViewPlugInInfo(Model model, PlugInInfo plugInInfo, boolean grayed) 
			throws FileReadingException, UnknownKeyException {
		super() ;
		this.model = model ;
		this.plugInInfo = plugInInfo ;
		this.build(grayed) ;
	}// ViewPlugInInfo(PlugInInfo, boolean)
	
	/**
	 * Builds the content of this view.
	 * 
	 * @param 	grayed
	 * 			whether the icon should be grayed out ({@code true} will 
	 * 			trigger the use of a grayed icon)
	 * 
	 * @throws 	FileReadingException
	 * 			if the format icon could not be loaded
	 * 
	 * @throws 	UnknownKeyException
	 * 			if an error occurred while updating the text of this view
	 */
	private void build(boolean grayed) 
			throws FileReadingException, UnknownKeyException {
		this.gridbag = new GridBagLayout() ;
		this.setLayout(this.gridbag) ;
		
		this.buildIcon(grayed) ;
		this.buildText() ;
	}// build(boolean)
	
	/**
	 * Builds the component displaying the icon of the displayed format (plug-in).
	 * 
	 * @param 	grayed
	 * 			whether the icon should be grayed out ({@code true} will 
	 * 			trigger the use of a grayed icon)
	 * 
	 * @throws 	FileReadingException
	 * 			if the format icon could not be loaded
	 */
	private void buildIcon(boolean grayed) 
			throws FileReadingException {
		GridBagConstraints constraints = new GridBagConstraints() ;
		constraints.weightx = 0.0 ;
		constraints.weighty = 0.0 ;
		constraints.gridwidth = 1 ;
		constraints.gridheight = GridBagConstraints.REMAINDER ;
		constraints.insets = new Insets(5, 5, 5, 5) ;
		constraints.anchor = GridBagConstraints.BASELINE ;
		
		this.plugInIcon = new JLabel(this.getIcon(grayed)) ;
		this.add(this.plugInIcon) ;
		this.gridbag.setConstraints(this.plugInIcon, constraints) ;
	}// buildIcon(boolean)
	
	/**
	 * Loads the icon of the displayed format (plug-in).
	 * 
	 * @param 	grayed
	 * 			whether the icon should be grayed out ({@code true} will 
	 * 			trigger the use of a grayed icon)
	 * 
	 * @return	{@code ImageIcon} containing the icon of the format
	 * 
	 * @throws 	FileReadingException
	 * 			if the format icon could not be loaded
	 */
	private ImageIcon getIcon(boolean grayed) throws FileReadingException {
		String iconPath = String.format(PATH_EXTENSION,
				PLUG_IN_RESOURCES_FOLDER,
				grayed ? FORMAT_GRAY_ICON_FILE_NAME 
						: FORMAT_ICON_FILE_NAME) ;
		String source = String.format(iconPath, this.plugInInfo.getId()) ;
		ImageIcon icon = null ;
		try {
			icon = new ImageIcon(ImageUtility.getImageBytes(source)) ;
		} catch (FileReadingException fre) {
			this.model.displayDebugInformation(fre) ;
			
			// Error while loading, resort to unknown format image
			InputStream isrc = new BufferedInputStream(
					this.getClass().getResourceAsStream(
					UNKNOWN_FORMAT_FILE)) ;
			isrc = new BufferedInputStream(isrc) ;
			icon = new ImageIcon(ImageUtility.getImageBytes(isrc)) ;
			try {
				isrc.close() ;
			} catch (IOException ioe) {
				throw new FileReadingException(new File(UNKNOWN_FORMAT_FILE)) ;
			}// try
		}// try
		
		return icon ;
	}// getIcon(boolean)
	
	/**
	 * Builds the textual description of the displayed plug-in.
	 * 
	 * @throws 	UnknownKeyException
	 * 			if an error occurred while updating the text of this view
	 */
	private void buildText() throws UnknownKeyException {
		GridBagLayout gridbagLayout = new GridBagLayout() ;
		JPanel container = new JPanel(gridbagLayout) ;
		GridBagConstraints containerConstraints = new GridBagConstraints() ;
		
		containerConstraints.weightx = 1.0 ;
		containerConstraints.weighty = 0.0 ;
		containerConstraints.gridwidth = GridBagConstraints.REMAINDER ;
		containerConstraints.gridheight = GridBagConstraints.REMAINDER ;
		containerConstraints.anchor = GridBagConstraints.BASELINE_LEADING ;
		
		this.add(container) ;
		this.gridbag.setConstraints(container, containerConstraints) ;
		
		GridBagConstraints labelConstraints, valueConstraints ;
		JLabel label, value ;		
		Font thisFont = this.getFont() ;
		Font valueFont = new Font(
				thisFont.getName(),
				Font.BOLD, 
				thisFont.getSize()) ;
		
		labelConstraints = new GridBagConstraints() ;
		labelConstraints.weightx = 0.0 ;
		labelConstraints.weighty = 0.0 ;
		labelConstraints.gridwidth = 1 ;
		labelConstraints.gridheight = 1 ;
		labelConstraints.anchor = GridBagConstraints.BASELINE_TRAILING ;
		labelConstraints.insets = new Insets(0, 0, 0, 5) ;
		
		valueConstraints = new GridBagConstraints() ;
		valueConstraints.weightx = 1.0 ;
		valueConstraints.weighty = 0.0 ;
		valueConstraints.gridwidth = GridBagConstraints.REMAINDER ;
		valueConstraints.gridheight = 1 ;
		valueConstraints.anchor = GridBagConstraints.BASELINE_LEADING ;
		
		String[] textKeys = new String[] {
				FORMAT, 
				EXTENSIONS, 
				EXECUTABLE
		} ;
		String[] values = new String[] {
				this.plugInInfo.getFormatName(), 
				Arrays.toString(this.plugInInfo.getExtensions())
					.replaceAll("[\\[\\]]", ""), //$NON-NLS-1$ //$NON-NLS-2$
				String.format("%s.kpl", this.plugInInfo.getJarName()) //$NON-NLS-1$
		} ;
		
		SwitchLanguage sl = SwitchLanguage.getInstance() ;
		int nRows = (textKeys.length == values.length) ? 
				textKeys.length : -1 ;
		for(int row=0; row < nRows; ++row) {
			label = new JLabel(sl.getText(textKeys[row])) ;
			value = new JLabel(values[row]) ;
			value.setFont(valueFont) ;
			
			container.add(label) ;
			gridbagLayout.setConstraints(label, labelConstraints) ;
			container.add(value) ;
			gridbagLayout.setConstraints(value, valueConstraints) ;
		}// for
	}// buildText()
	
	/**
	 * Grays or colors the displayed icon.
	 * 
	 * @param 	grayed
	 * 			whether the icon should be grayed out ({@code true} will 
	 * 			trigger the use of a grayed icon) 			
	 * 
	 * @throws 	FileReadingException
	 * 			if the format icon could not be loaded
	 */
	public void setIconIsGrayed(boolean grayed) 
			throws FileReadingException {
		this.plugInIcon.setIcon(this.getIcon(grayed)) ;
	}// setIconIsGrayed(boolean)
	
}// class ViewPlugInInfo